package com.haohan.jingyuan.customer.service;

import com.haohan.jingyuan.customer.dao.CustomerFileMapper;
import com.haohan.jingyuan.customer.dao.CustomerIncomeMapper;
import com.haohan.jingyuan.customer.dao.CustomerIncomeTypeMapper;
import com.haohan.jingyuan.customer.dao.CustomerInfoMapper;
import com.haohan.jingyuan.customer.dto.req.QueryReportDateRangeRequest;
import com.haohan.jingyuan.customer.dto.resp.CustomerIncomeResp;
import com.haohan.jingyuan.customer.dto.resp.IncomeTypeIncomeResp;
import com.haohan.jingyuan.customer.dto.resp.IndustryDistributionResp;
import com.haohan.jingyuan.customer.dto.resp.MonthlyExpireFileResp;
import com.haohan.jingyuan.customer.dto.resp.TotalCountResp;
import com.haohan.jingyuan.customer.entity.CustomerIncomeType;
import com.haohan.jingyuan.customer.entity.CustomerInfo;
import com.haohan.jingyuan.sys.service.DictService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 客户报表服务实现类
 *
 * @ClassName CustomerReportService
 * @Description 客户报表相关业务逻辑实现
 * @Author hexijun
 * @Time 2025/01/19 10:00
 * @Version 1.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CustomerReportService {

    /**
     * 客户信息Mapper
     */
    private final CustomerInfoMapper customerInfoMapper;

    /**
     * 客户文件Mapper
     */
    private final CustomerFileMapper customerFileMapper;

    /**
     * 客户收入Mapper
     */
    private final CustomerIncomeMapper customerIncomeMapper;

    /**
     * 客户收入类型Mapper
     */
    private final CustomerIncomeTypeMapper customerIncomeTypeMapper;

    /**
     * 字典服务
     */
    private final DictService dictService;

    /**
     * 查询总数
     *
     * @return 总数统计
     */
    public TotalCountResp queryTotalCount() {
        log.info("CustomerReportService.queryTotalCount BEGIN");

        // 统计总客户数
        Long totalCustomerCount = customerInfoMapper.countTotalCustomers();
        if (totalCustomerCount == null) {
            totalCustomerCount = 0L;
        }

        // 统计总文档数
        Long totalFileCount = customerFileMapper.countTotalFiles();
        if (totalFileCount == null) {
            totalFileCount = 0L;
        }

        // 统计总实收客户收入
        BigDecimal totalReceivedAmount = customerIncomeMapper.sumTotalReceivedAmount();
        if (totalReceivedAmount == null) {
            totalReceivedAmount = BigDecimal.ZERO;
        }

        TotalCountResp response = new TotalCountResp();
        response.setTotalCustomerCount(totalCustomerCount);
        response.setTotalFileCount(totalFileCount);
        response.setTotalReceivedAmount(totalReceivedAmount);

        log.info("CustomerReportService.queryTotalCount END ==> {}", response);
        return response;
    }

    /**
     * 服务类型收入
     *
     * @param request 查询日期范围请求
     * @return 服务类型收入列表
     */
    public List<IncomeTypeIncomeResp> queryIncomeTypeIncome(QueryReportDateRangeRequest request) {
        log.info("CustomerReportService.queryIncomeTypeIncome BEGIN ==> {}", request);

        // 根据收入类型分组统计
        List<Map<String, Object>> groupList = customerIncomeMapper.groupByIncomeType(
                request.getStartTime(), request.getEndTime());

        // 计算总金额
        BigDecimal totalAmount = groupList.stream()
                .map(item -> {
                    Object amount = item.get("totalAmount");
                    return amount instanceof BigDecimal ? (BigDecimal) amount : new BigDecimal(amount.toString());
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 查询所有收入类型
        List<CustomerIncomeType> incomeTypeList = customerIncomeTypeMapper.selectAll();
        Map<String, String> incomeTypeMap = incomeTypeList.stream()
                .collect(Collectors.toMap(CustomerIncomeType::getType, CustomerIncomeType::getTypeName));

        // 转换为响应对象并计算占比
        List<IncomeTypeIncomeResp> respList = new ArrayList<>();
        for (Map<String, Object> item : groupList) {
            IncomeTypeIncomeResp resp = new IncomeTypeIncomeResp();
            String incomeType = (String) item.get("incomeType");
            resp.setIncomeTypeName(incomeTypeMap.getOrDefault(incomeType, incomeType));
            
            Object amount = item.get("totalAmount");
            BigDecimal total = amount instanceof BigDecimal ? (BigDecimal) amount : new BigDecimal(amount.toString());
            resp.setTotalAmount(total);
            
            // 计算占比
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal percentage = total.divide(totalAmount, 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"))
                        .setScale(2, RoundingMode.HALF_UP);
                resp.setPercentage(percentage);
            } else {
                resp.setPercentage(BigDecimal.ZERO);
            }
            
            respList.add(resp);
        }

        log.info("CustomerReportService.queryIncomeTypeIncome END ==> size: {}", respList.size());
        return respList;
    }

    /**
     * 客户收入
     *
     * @param request 查询日期范围请求
     * @return 客户收入列表
     */
    public List<CustomerIncomeResp> queryCustomerIncome(QueryReportDateRangeRequest request) {
        log.info("CustomerReportService.queryCustomerIncome BEGIN ==> {}", request);

        // 根据客户ID分组统计
        List<Map<String, Object>> groupList = customerIncomeMapper.groupByCustomerId(
                request.getStartTime(), request.getEndTime());

        // 计算总金额
        BigDecimal totalAmount = groupList.stream()
                .map(item -> {
                    Object amount = item.get("totalAmount");
                    return amount instanceof BigDecimal ? (BigDecimal) amount : new BigDecimal(amount.toString());
                })
                .reduce(BigDecimal.ZERO, BigDecimal::add);

        // 批量查询客户信息
        Set<String> customerIds = groupList.stream()
                .map(item -> (String) item.get("customerId"))
                .collect(Collectors.toSet());
        Map<String, String> customerNameMap = new HashMap<>();
        for (String customerId : customerIds) {
            CustomerInfo customerInfo = customerInfoMapper.findByCustomerId(customerId);
            if (customerInfo != null) {
                customerNameMap.put(customerId, customerInfo.getName());
            }
        }

        // 转换为响应对象并计算占比
        List<CustomerIncomeResp> respList = new ArrayList<>();
        for (Map<String, Object> item : groupList) {
            CustomerIncomeResp resp = new CustomerIncomeResp();
            String customerId = (String) item.get("customerId");
            resp.setCustomerName(customerNameMap.getOrDefault(customerId, customerId));
            
            Object amount = item.get("totalAmount");
            BigDecimal total = amount instanceof BigDecimal ? (BigDecimal) amount : new BigDecimal(amount.toString());
            resp.setTotalAmount(total);
            
            // 计算占比
            if (totalAmount.compareTo(BigDecimal.ZERO) > 0) {
                BigDecimal percentage = total.divide(totalAmount, 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"))
                        .setScale(2, RoundingMode.HALF_UP);
                resp.setPercentage(percentage);
            } else {
                resp.setPercentage(BigDecimal.ZERO);
            }
            
            respList.add(resp);
        }

        log.info("CustomerReportService.queryCustomerIncome END ==> size: {}", respList.size());
        return respList;
    }

    /**
     * 客户行业分布
     *
     * @return 客户行业分布列表
     */
    public List<IndustryDistributionResp> queryIndustryDistribution() {
        log.info("CustomerReportService.queryIndustryDistribution BEGIN");

        // 根据行业分组统计
        List<Map<String, Object>> groupList = customerInfoMapper.groupByIndustry();

        // 计算总客户数
        Long totalCount = groupList.stream()
                .mapToLong(item -> {
                    Object count = item.get("customerCount");
                    return count instanceof Long ? (Long) count : Long.parseLong(count.toString());
                })
                .sum();

        // 查询行业字典
        Map<String, String> industryMap = dictService.getAllIndustryType();

        // 转换为响应对象并计算占比
        List<IndustryDistributionResp> respList = new ArrayList<>();
        for (Map<String, Object> item : groupList) {
            IndustryDistributionResp resp = new IndustryDistributionResp();
            String industry = (String) item.get("industry");
            resp.setIndustryName(industryMap.getOrDefault(industry, industry));
            
            Object count = item.get("customerCount");
            Long customerCount = count instanceof Long ? (Long) count : Long.parseLong(count.toString());
            resp.setCustomerCount(customerCount);
            
            // 计算占比
            if (totalCount > 0) {
                BigDecimal percentage = new BigDecimal(customerCount)
                        .divide(new BigDecimal(totalCount), 4, RoundingMode.HALF_UP)
                        .multiply(new BigDecimal("100"))
                        .setScale(2, RoundingMode.HALF_UP);
                resp.setPercentage(percentage);
            } else {
                resp.setPercentage(BigDecimal.ZERO);
            }
            
            respList.add(resp);
        }

        log.info("CustomerReportService.queryIndustryDistribution END ==> size: {}", respList.size());
        return respList;
    }

    /**
     * 材料到期时间分布
     *
     * @return 月度到期文件列表
     */
    public List<MonthlyExpireFileResp> queryMonthlyExpireFile() {
        log.info("CustomerReportService.queryMonthlyExpireFile BEGIN");

        // 计算近6个月的开始和结束月份（从当前自然月开始，连续6个月）
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        // 开始月份是当前月份
        String startMonth = sdf.format(calendar.getTime());
        
        // 结束月份是当前月份+5个月（共6个月）
        calendar.add(Calendar.MONTH, 5);
        String endMonth = sdf.format(calendar.getTime());

        // 根据月份和文件类型分组统计
        List<Map<String, Object>> groupList = customerFileMapper.groupByMonthAndFileType(startMonth, endMonth);

        // 构建月份Map，key为月份，value为包含合同和材料数量的Map
        Map<String, Map<String, Long>> monthDataMap = new LinkedHashMap<>();
        
        // 初始化所有月份（从当前自然月开始，连续6个月）
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        for (int i = 0; i < 6; i++) {
            String month = sdf.format(calendar.getTime());
            Map<String, Long> typeMap = new HashMap<>();
            typeMap.put("contract", 0L);
            typeMap.put("material", 0L);
            monthDataMap.put(month, typeMap);
            calendar.add(Calendar.MONTH, 1);
        }

        // 填充统计数据
        for (Map<String, Object> item : groupList) {
            String month = (String) item.get("month");
            String fileType = (String) item.get("fileType");
            Object count = item.get("fileCount");
            Long fileCount = count instanceof Long ? (Long) count : Long.parseLong(count.toString());
            
            Map<String, Long> typeMap = monthDataMap.get(month);
            if (typeMap != null) {
                // 假设 fileType 为 "合同" 或包含 "合同" 的是合同文档，其他是材料文档
                if (fileType != null && (fileType.contains("合同") || fileType.equals("contract"))) {
                    typeMap.put("contract", typeMap.get("contract") + fileCount);
                } else {
                    typeMap.put("material", typeMap.get("material") + fileCount);
                }
            }
        }

        // 转换为响应对象
        List<MonthlyExpireFileResp> respList = new ArrayList<>();
        for (Map.Entry<String, Map<String, Long>> entry : monthDataMap.entrySet()) {
            MonthlyExpireFileResp resp = new MonthlyExpireFileResp();
            resp.setMonth(entry.getKey());
            Map<String, Long> typeMap = entry.getValue();
            resp.setContractCount(typeMap.get("contract"));
            resp.setMaterialCount(typeMap.get("material"));
            respList.add(resp);
        }

        log.info("CustomerReportService.queryMonthlyExpireFile END ==> size: {}", respList.size());
        return respList;
    }
}

